$OpenBSD: patch-gcc_targhooks_c,v 1.3 2013/06/07 07:54:23 pascal Exp $
--- gcc/targhooks.c.orig	Fri Aug 10 15:26:44 2012
+++ gcc/targhooks.c	Sat Apr 13 16:20:32 2013
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "expr.h"
 #include "output.h"
+#include "c-family/c-common.h"
 #include "diagnostic-core.h"
 #include "function.h"
 #include "target.h"
@@ -658,7 +659,7 @@ default_stack_protect_guard (void)
       rtx x;
 
       t = build_decl (UNKNOWN_LOCATION,
-		      VAR_DECL, get_identifier ("__stack_chk_guard"),
+		      VAR_DECL, get_identifier ("__guard_local"),
 		      ptr_type_node);
       TREE_STATIC (t) = 1;
       TREE_PUBLIC (t) = 1;
@@ -667,6 +668,8 @@ default_stack_protect_guard (void)
       TREE_THIS_VOLATILE (t) = 1;
       DECL_ARTIFICIAL (t) = 1;
       DECL_IGNORED_P (t) = 1;
+      DECL_VISIBILITY (t) = VISIBILITY_HIDDEN;
+      DECL_VISIBILITY_SPECIFIED (t) = 1;
 
       /* Do not share RTL as the declaration is visible outside of
 	 current function.  */
@@ -679,67 +682,68 @@ default_stack_protect_guard (void)
   return t;
 }
 
-static GTY(()) tree stack_chk_fail_decl;
+static GTY(()) int stack_protect_labelno;
 
 tree
 default_external_stack_protect_fail (void)
 {
-  tree t = stack_chk_fail_decl;
+  tree t, func, type, init, stack_smash_handler;
+  const char *name;
+  size_t length;
+  char name_buf[32];
 
-  if (t == NULL_TREE)
-    {
-      t = build_function_type_list (void_type_node, NULL_TREE);
-      t = build_decl (UNKNOWN_LOCATION,
-		      FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t);
-      TREE_STATIC (t) = 1;
-      TREE_PUBLIC (t) = 1;
-      DECL_EXTERNAL (t) = 1;
-      TREE_USED (t) = 1;
-      TREE_THIS_VOLATILE (t) = 1;
-      TREE_NOTHROW (t) = 1;
-      DECL_ARTIFICIAL (t) = 1;
-      DECL_IGNORED_P (t) = 1;
-      DECL_VISIBILITY (t) = VISIBILITY_DEFAULT;
-      DECL_VISIBILITY_SPECIFIED (t) = 1;
+  if (NULL == (name = fname_as_string (0))) {
+	name = (char *)xmalloc(32);
+	strlcpy (name, "*unknown*", 32);
+  }
+  length = strlen (name);
+  /* Build a decl for __func__. */
+  type = build_array_type (char_type_node,
+			build_index_type (size_int (length)));
+  type = build_qualified_type (type, TYPE_QUAL_CONST);
 
-      stack_chk_fail_decl = t;
-    }
+  init = build_string (length + 1, name);
+  free ((char *) name);
+  TREE_TYPE (init) = type;
 
-  return build_call_expr (t, 0);
+  func = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, type);
+  TREE_STATIC (func) = 1;
+  TREE_READONLY (func) = 1;
+  DECL_ARTIFICIAL (func) = 1;
+  ASM_GENERATE_INTERNAL_LABEL (name_buf, "LSSH", stack_protect_labelno++);
+  DECL_NAME (func) = get_identifier (name_buf);
+  DECL_INITIAL (func) = init;
+
+  assemble_variable (func, 0, 0, 0);
+
+  /* Build a decl for __stack_smash_handler. */
+  t = build_pointer_type (TREE_TYPE (func));
+  t = build_function_type_list (void_type_node, t, NULL_TREE);
+  t = build_decl (UNKNOWN_LOCATION,
+  		  FUNCTION_DECL, get_identifier ("__stack_smash_handler"), t);
+  /* t = build_fn_decl ("__stack_smash_handler", t); */
+  TREE_STATIC (t) = 1;
+  TREE_PUBLIC (t) = 1;
+  DECL_EXTERNAL (t) = 1;
+  TREE_USED (t) = 1;
+  TREE_THIS_VOLATILE (t) = 1;
+  TREE_NOTHROW (t) = 1;
+  DECL_ARTIFICIAL (t) = 1;
+  DECL_IGNORED_P (t) = 1;
+  DECL_VISIBILITY (t) = VISIBILITY_DEFAULT;
+  DECL_VISIBILITY_SPECIFIED (t) = 1;
+
+  stack_smash_handler = t;
+
+  /* Generate a call to __stack_smash_handler(__func__). */
+  t = build_fold_addr_expr (func);
+  return build_call_expr (stack_smash_handler, 1, t);
 }
 
 tree
 default_hidden_stack_protect_fail (void)
 {
-#ifndef HAVE_GAS_HIDDEN
   return default_external_stack_protect_fail ();
-#else
-  tree t = stack_chk_fail_decl;
-
-  if (!flag_pic)
-    return default_external_stack_protect_fail ();
-
-  if (t == NULL_TREE)
-    {
-      t = build_function_type_list (void_type_node, NULL_TREE);
-      t = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
-		      get_identifier ("__stack_chk_fail_local"), t);
-      TREE_STATIC (t) = 1;
-      TREE_PUBLIC (t) = 1;
-      DECL_EXTERNAL (t) = 1;
-      TREE_USED (t) = 1;
-      TREE_THIS_VOLATILE (t) = 1;
-      TREE_NOTHROW (t) = 1;
-      DECL_ARTIFICIAL (t) = 1;
-      DECL_IGNORED_P (t) = 1;
-      DECL_VISIBILITY_SPECIFIED (t) = 1;
-      DECL_VISIBILITY (t) = VISIBILITY_HIDDEN;
-
-      stack_chk_fail_decl = t;
-    }
-
-  return build_call_expr (t, 0);
-#endif
 }
 
 bool
